package org.rule.emum;


import com.googlecode.aviator.AviatorEvaluatorInstance;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.rule.domain.dto.RuleExecDTO;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;

@Getter
@AllArgsConstructor
public enum OperatorEnum {
    STR_EQ("STR_EQ", "==","equal") {
        @Override
        public String buildExpression(RuleExecDTO rule)  {
            return "str_equal("+rule.getFstParam()+", param)";
        }

        @Override
        public boolean compare(AviatorEvaluatorInstance evaluator, Map<String, Object> map, RuleExecDTO rule) {
            return  (Boolean)evaluator.execute(this.buildExpression(rule), map);
        }
    }
    ,NUM_EQ("NUM_EQ", "==", "number equal") {
        @Override
        public String buildExpression(RuleExecDTO rule)  {
            return "num_equal("+rule.getFstParam()+", param)";
        }

        @Override
        public boolean compare(AviatorEvaluatorInstance evaluator, Map<String, Object> map, RuleExecDTO rule) {
            return (Long)evaluator.execute(this.buildExpression(rule), map)==0;
        }
    }, NUM_GT( "NUM_GT",">","grater than") {
        @Override
        public String buildExpression(RuleExecDTO rule)  {
            return "num_equal("+rule.getFstParam()+", param)";
        }

        @Override
        public boolean compare(AviatorEvaluatorInstance evaluator, Map<String, Object> map, RuleExecDTO rule) {
            return (Long)evaluator.execute(this.buildExpression(rule), map)==1;
        }
    }, NUM_LT("NUM_LT", "<","less than") {
        @Override
        public String buildExpression(RuleExecDTO rule)  {
            return "num_equal("+rule.getFstParam()+", param)";
        }

        @Override
        public boolean compare(AviatorEvaluatorInstance evaluator, Map<String, Object> map, RuleExecDTO rule) {
            return  (Long)evaluator.execute(this.buildExpression(rule), map)==-1;
        }
    }, STR_NE("STR_NE", "!=","not equal") {
        @Override
        public String buildExpression(RuleExecDTO rule)  {
            return "str_not_equal("+rule.getFstParam()+", param)";
        }

        @Override
        public boolean compare(AviatorEvaluatorInstance evaluator, Map<String, Object> map, RuleExecDTO rule) {
            return  (Boolean)evaluator.execute(this.buildExpression(rule), map);
        }
    }, OBJ_NOT_NULL("OBJ_NOT_NULL","ONN", "object not null") {
        @Override
        public String buildExpression(RuleExecDTO rule)  {
            return "obj_not_null("+rule.getFstParam()+")";
        }

        @Override
        public boolean compare(AviatorEvaluatorInstance evaluator, Map<String, Object> map, RuleExecDTO rule) {
            return  (Boolean)evaluator.execute(this.buildExpression(rule), map);
        }
    }, LIST_IN("LIST_IN", "LIST_IN", "contains, split with ,") {
        @Override
        public String buildExpression(RuleExecDTO rule)  {
            return "list_in("+rule.getFstParam()+",param)";
        }

        @Override
        public boolean compare(AviatorEvaluatorInstance evaluator, Map<String, Object> map, RuleExecDTO rule) {
            return  (Boolean)evaluator.execute(this.buildExpression(rule), map);
        }
    };
    /**
     * 操作符
     */
    final String operator;
    /**
     * 符号
     */
    final String symbol;
    /**
     * 描述
     */
    final String desc;
    public abstract String buildExpression(RuleExecDTO rule) throws Exception;
    public abstract boolean compare(AviatorEvaluatorInstance evaluator, Map<String, Object> map, RuleExecDTO rule);
    public final static Map<String, OperatorEnum> operatorMap = Arrays.stream(OperatorEnum.values()).collect(Collectors.toMap(OperatorEnum::getOperator, e->e));
    public static OperatorEnum getOperator(String operator){
        return operatorMap.get(operator);
    }
}
